package com.vooda.service.impl;

import com.vooda.dao.MarketDao;
import com.vooda.dao.StoreDao;
import com.vooda.dto.vo.BaseResult;
import com.vooda.dto.vo.MarketVo;
import com.vooda.dto.vo.StoreVo;
import com.vooda.entity.Market;
import com.vooda.entity.Store;
import com.vooda.service.MarketService;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author KennyDavid
 */

@Service
public class MarketServiceImpl implements MarketService {

    private MarketDao marketDao;
    private StoreDao storeDao;

    public MarketServiceImpl(MarketDao marketDao, StoreDao storeDao) {
        this.marketDao = marketDao;
        this.storeDao = storeDao;
    }


    @Override
    public BaseResult<List<MarketVo>> getMarketList(Date createTime, Integer size) {
        List<MarketVo> dtos = new ArrayList<>();
        MarketVo marketVo;
        List<StoreVo> storeVos;
        StoreVo storeVo;

        Page<Market> pages = marketDao.findAll((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();

            Predicate predicate1 = criteriaBuilder.equal(root.get("isDel").as(Boolean.class), false);
            Predicate predicate2;
            if (ObjectUtils.isEmpty(createTime)) {
                predicate2 = criteriaBuilder.lessThan(root.get("createTime").as(Date.class), new Date());
            } else {
                predicate2 = criteriaBuilder.lessThan(root.get("createTime").as(Date.class), createTime);
            }

            predicates.add(predicate1);
            predicates.add(predicate2);

            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        }, new PageRequest(0, size, new Sort(Sort.Direction.DESC, "createTime")));

        for (Market market : pages.getContent()) {
            marketVo = new MarketVo();
            BeanUtils.copyProperties(market, marketVo);
            storeVos = new ArrayList<>();
            List<Store> stores = storeDao.findTop4ByIsDelAndMarketIdOrderByCreateTimeDesc(false, market.getId());
            for (Store store : stores) {
                if (!ObjectUtils.isEmpty(store)) {
                    storeVo = new StoreVo();
                    BeanUtils.copyProperties(store, storeVo);
                    storeVo.setImageUrl("https://yihubaiying.org/data_cdn/" + store.getImageUrl());
                    storeVos.add(storeVo);
                }
            }
            marketVo.setStoreVos(storeVos);
            dtos.add(marketVo);
        }
        return new BaseResult<>(dtos);
    }

    @Override
    public BaseResult<List<StoreVo>> getMoreStore(Long marketId, Date createTime, Integer size) {
        List<StoreVo> storeVos = new ArrayList<>();
        StoreVo storeVo;

        Page<Store> pages = storeDao.findAll((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();

            Predicate predicate1 = criteriaBuilder.equal(root.get("isDel").as(Boolean.class), false);
            Predicate predicate2;
            if (ObjectUtils.isEmpty(createTime)) {
                predicate2 = criteriaBuilder.lessThan(root.get("createTime").as(Date.class), new Date());
            } else {
                predicate2 = criteriaBuilder.lessThan(root.get("createTime").as(Date.class), createTime);
            }
            Predicate predicate3 = criteriaBuilder.equal(root.get("marketId").as(Long.class), marketId);

            predicates.add(predicate1);
            predicates.add(predicate2);
            predicates.add(predicate3);

            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        }, new PageRequest(0, size, new Sort(Sort.Direction.DESC, "createTime")));

        for (Store store : pages.getContent()) {
            storeVo = new StoreVo();
            BeanUtils.copyProperties(store, storeVo);
            storeVo.setImageUrl("https://yihubaiying.org/data_cdn/" + store.getImageUrl());
            storeVos.add(storeVo);
        }

        return new BaseResult<>(storeVos);
    }
}
